using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Pbdms.Common.DataObject;
using System.Threading;
using System.Collections;
using Pbdms.BusinessLogic.FileTransfer;

namespace Pbdms.Forms.Tools
{
    public partial class FrmLibraryTransfer : Form
    {
        private ResultItem copyItem;
        Thread thStart =null;
        private Boolean finished=false;
        private string keyID;
        
        private Boolean hasFile = false;
        private Boolean hasReviewFile =false;
        private Boolean fileFinished=false;
        private Boolean reviewFileFinished=false;
        /// <summary>
        /// delegate handler to invoke GUI
        /// </summary>
        /// <param name="fileTransfer"></param>
        private delegate void workerDelegate(FileTransferGui fileTransfer);
        /// <summary>
        /// when there are no files to download
        /// </summary>
        private delegate void noFilesDelegate();
        /// <summary>
        /// delegate method to invoke display method
        /// </summary>
        /// <param name="keyid"></param>
        /// <param name="name"></param>
        /// <param name="author"></param>
        /// <param name="title"></param>
        private delegate void guiDelegate(string keyid,string name, string author, string title);
        public FrmLibraryTransfer()
        {
            InitializeComponent();
            this.Shown += new EventHandler(FrmLibraryTransfercs_Shown);
        }

        void FrmLibraryTransfercs_Shown(object sender, EventArgs e)
        {
            thStart= new Thread(new ThreadStart(start));
            thStart.Start();
        }
     
        public void setResultItem(ResultItem item)
        {
            //deep copying
            copyItem = new ResultItem();
            
            //copy all itemobj          
            copyItem.ItemObj = new Common.DataObject.Item();
            copyItem.ItemObj.BibTexes = item.ItemObj.BibTexes;
            copyItem.ItemObj.BPrivate = false;
            copyItem.ItemObj.Category = item.ItemObj.Category;
            copyItem.ItemObj.Id = item.ItemObj.Id;

            copyItem.FileInfoObj = new Pbdms.Common.DataObject.FileInfo();
            copyItem.FileInfoObj.Existence = item.FileInfoObj.Existence;
            copyItem.FileInfoObj.FileName = item.FileInfoObj.FileName;
            copyItem.FileInfoObj.Location = item.FileInfoObj.Location;
            copyItem.FileInfoObj.Size = item.FileInfoObj.Size;
            copyItem.FileInfoObj.ID = item.FileInfoObj.ID;

            copyItem.CommentObj = new Comment();
            copyItem.CommentObj.Cons = item.CommentObj.Cons;
            copyItem.CommentObj.Pros = item.CommentObj.Pros;
            copyItem.CommentObj.Rating = item.CommentObj.Rating;
            copyItem.CommentObj.ReviewFile = item.CommentObj.ReviewFile;
            copyItem.CommentObj.Summary = item.CommentObj.Summary;
            copyItem.CommentObj.Tags = item.CommentObj.Tags;
            copyItem.CommentObj.Id = item.CommentObj.Id;
        }
        public ResultItem getItem()
        {
            return copyItem;
        }

        public Boolean isFinished(){
            return finished;
        }
        /// <summary>
        /// set display information
        /// </summary>
        /// <param name="keyid"></param>
        /// <param name="name"></param>
        /// <param name="title"></param>
        /// <param name="author"></param>
        private void setInfo(string keyid,string name, string title, string author)
        {

            if (InvokeRequired)
            {
                guiDelegate guiworker = new guiDelegate(setInfo);
                this.Invoke(guiworker, new object[] {keyid,name,title,author});
            }
            else
            {
                this.lblUser.Text = name;
                this.keyID = keyid;
                this.lblInfo.Text = "Downloadin a library collection with the title (" + title + ") and the author (" + author + ")";
            }
        }

        /// <summary>
        /// add a file transfer object
        /// </summary>
        /// <param name="fileTransfer"></param>
        public void addControl(FileTransferGui fileTransfer)
        {
            if (InvokeRequired)
            {
                workerDelegate worker = new workerDelegate(addControl);
                this.Invoke(worker, new object[] {fileTransfer });
            }
            else
            {
                fileTransfer.CancelClicked += new EventHandler(file_CancelClicked);
                fileTransfer.FinishedEvent += new FileTransferGui.FinishedEventHandler(FileTransferGui_FinishedEvent);
                fileTransfer.Dock = DockStyle.Top;
                
                fileTransfer.start();
                this.panelDisplay.Controls.Add(fileTransfer);
            }

        }

        private void noFileEvent()
        {
            if (InvokeRequired)
            {
                noFilesDelegate noFilesWorker = new noFilesDelegate(noFileEvent);
                this.Invoke(noFilesWorker);
            }
            else
            {
                this.btnCancel.Text = "Done";
            }
        }



        /// <summary>
        /// control finished event
        /// </summary>
        /// <param name="sender"></param>
        private void FileTransferGui_FinishedEvent(object sender)
        {
            if (InvokeRequired)
            {
                workerDelegate dele = new workerDelegate(FileTransferGui_FinishedEvent);
                this.Invoke(dele, new object[] { sender });
            }
            else
            {
                lock (this)
                {
                    BusinessLogic.FileTransfer.LibraryTransferReceiverGui file = (BusinessLogic.FileTransfer.LibraryTransferReceiverGui)sender;
                    //download finished

                    if (file.FileType.Equals("1"))
                    {
                        fileFinished = true;
                     
                    }
                    else if (file.FileType.Equals("2"))
                    {
                        reviewFileFinished = true;
                        
                    }
                    //got 2 files
                    if (hasFile == true && hasReviewFile == true)
                    {
                        if ((fileFinished == true && hasFile) && (reviewFileFinished == true))
                        {
                            this.btnCancel.Text = "Done";
                        }
                    }//got 1 file
                    else if(hasFile==true&&hasReviewFile==false)
                    {
                        if (fileFinished == true)
                        {
                            this.btnCancel.Text = "Done";
                        }
                    }//got review file
                    else if (hasFile == false && hasReviewFile == true)
                    {
                        if (reviewFileFinished == true)
                        {
                            this.btnCancel.Text = "Done";
                        }
                    }

                }
            }

        }

        /// <summary>
        /// remove the user control object
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void file_CancelClicked(object sender, EventArgs e)
        {
            lock (this)
            {
                BusinessLogic.FileTransfer.LibraryTransferReceiverGui file = (BusinessLogic.FileTransfer.LibraryTransferReceiverGui)sender;
                //download finished
                if (file.Finished() == true)
                {
                    if (file.FileType.Equals("1"))
                    {
                        fileFinished = true;

                    }
                    else if (file.FileType.Equals("2"))
                    {
                        reviewFileFinished = true;
                    }
                }
                else
                {
                    if (file.FileType.Equals("1"))
                    {
                        hasFile = false;

                    }
                    else if (file.FileType.Equals("2"))
                    {
                        hasReviewFile = false;
                    }
                    this.panelDisplay.Controls.Remove(file);
                }

               
                //got 2 files
                if (hasFile == true && hasReviewFile == true)
                {
                    if ((fileFinished == true && hasFile) && (reviewFileFinished == true))
                    {
                        this.btnCancel.Text = "Done";
                    }
                }//got 1 file
                else if (hasFile == true && hasReviewFile == false)
                {
                    if (fileFinished == true)
                    {
                        this.btnCancel.Text = "Done";
                    }
                }//got review file
                else if (hasFile == false && hasReviewFile == true)
                {
                    if (reviewFileFinished == true)
                    {
                        this.btnCancel.Text = "Done";
                    }
                }
                else if (hasFile == false && hasReviewFile == false)
                {
                    this.btnCancel.Text = "Done";
                }

            }
            
        }
     
      




      

        private void start(){
            try
            {
                Buddy buddy = Program.friendControl.getAFriendByIP(copyItem.FileInfoObj.Location);
                string username=copyItem.FileInfoObj.Location;
                string keyid = "";
                if (buddy != null)
                {
                    username=buddy.Name;
                    keyid = buddy.KeyID;
                }
                string []data= getItemArrayForDataRow(copyItem.ItemObj.BibTexes);
                setInfo(keyid, username, data[0], data[1]);
                AppSetting aSetting = new AppSetting();
               
                string IP = copyItem.FileInfoObj.Location;
                
                Boolean cond1=copyItem.FileInfoObj.Existence;
                Boolean cond2=!copyItem.FileInfoObj.FileName.Equals("");
                Boolean cond3=!copyItem.CommentObj.ReviewFile.Trim().Equals("");
            
                if (( cond1== true && cond2 )
                    || (cond3==true))
                {
                   
                    //check the files' name
                    if ((copyItem.FileInfoObj.Existence == true && System.IO.File.Exists(aSetting.LibFolder + "\\" + copyItem.FileInfoObj.FileName) == true)
                        || (!copyItem.CommentObj.ReviewFile.Trim().Equals("") && System.IO.File.Exists(aSetting.LibFolder + "\\" + copyItem.CommentObj.ReviewFile) == true))
                    {
                        int dlgResult = Common.Global.showMsgTwoButtons("Duplicate file(s) in the library!\r\nWould you like to save to seperate file(s)?\r\nSelect \"No\" to overwrite",
                            Common.GUI.MsgBoxTwoButtons.YES_NO, 'I');
                        if (dlgResult == Common.GUI.MsgBoxTwoButtons.DIALOG_RESULT_YES)
                        {
                            //assign the name for the file
                            if (copyItem.FileInfoObj.Existence == true
                                && System.IO.File.Exists(aSetting.LibFolder + "\\" + copyItem.FileInfoObj.FileName))
                            {
                                int i = 2;
                                string tempFileName = copyItem.FileInfoObj.FileName;
                                while (System.IO.File.Exists(Common.Global.getLibFolder() + "\\" + tempFileName))
                                {

                                    tempFileName = copyItem.FileInfoObj.FileName.Insert(copyItem.FileInfoObj.FileName.IndexOf("."), "_" + i.ToString());
                                    i++;
                                }
                                copyItem.FileInfoObj.FileName = tempFileName;
                                hasFile = true;
                            }
                            //assign the name for the file
                            if (!copyItem.CommentObj.ReviewFile.Trim().Equals(""))
                            {
                                int i = 2;
                                string tempFileName = copyItem.CommentObj.ReviewFile;
                                while (System.IO.File.Exists(Common.Global.getLibFolder() + "\\" + tempFileName))
                                {
                                    tempFileName = copyItem.CommentObj.ReviewFile.Insert(copyItem.CommentObj.ReviewFile.IndexOf("."), "_" + i.ToString());
                                    i++;
                                }
                                copyItem.CommentObj.ReviewFile = tempFileName;
                                hasReviewFile = true;
                            }
                        }
                    }
                    else
                    {
                        if (!copyItem.CommentObj.ReviewFile.Trim().Equals(""))
                        {
                            hasReviewFile = true;
                            
                        }
                        else if (!copyItem.FileInfoObj.FileName.Equals(""))
                        {
                            hasFile = true;
                        }
                    }
                    //download files
                 
                    try
                    {
                        //has file
                        if (hasFile==true)
                        {
                            System.IO.FileInfo fileInfo = new System.IO.FileInfo(Common.Global.getLibFolder() + "\\" + copyItem.FileInfoObj.FileName);
                            BusinessLogic.FileTransfer.LibraryTransferReceiverGui libraryReceiver = new BusinessLogic.FileTransfer.LibraryTransferReceiverGui(copyItem.ItemObj.Id, "1", fileInfo, Program.friendControl, IP, Program.networkCtrller);
                            this.addControl(libraryReceiver);

                           


                        }
                        //has review file
                        if(hasReviewFile==true)
                        {
             

                            System.IO.FileInfo fileInfo1 = new System.IO.FileInfo(Common.Global.getLibFolder() + "\\" + copyItem.CommentObj.ReviewFile);
                            BusinessLogic.FileTransfer.LibraryTransferReceiverGui libraryReceiver2 = new BusinessLogic.FileTransfer.LibraryTransferReceiverGui(copyItem.ItemObj.Id, "2", fileInfo1, Program.friendControl, IP, Program.networkCtrller);

                            this.addControl(libraryReceiver2); ;
                            
                            
                        }
                       
                      
                        //modify the path to the newly copied review file

  
                        copyItem.SourceOfItem = ResultItem.ITEM_SOURCE_LOCAL;

                       
                    }
                    catch
                    {
                        MessageBox.Show("Error downloading the files");
                    }
                    
                }
                if (hasFile==false&&hasReviewFile==false)
                {
                    noFileEvent();
                }
                    
            }
            catch
            {

            }
        }
        /// <summary>
        /// construct string array
        /// </summary>
        /// <param name="arlOfBibTexese"></param>
        /// <returns></returns>
        private string[] getItemArrayForDataRow(ArrayList arlOfBibTexese)
        {
            //itemArray describe the data row in the gridview
            string[] itemArray = new string[9];
            /*
            for (int i = 0; i < 11; i++)
            {
                itemArray[i] = "";
            }
            //first value is index number
            itemArray[0] = iCount.ToString();
            itemArray[1] = matchPercentage.ToString();
            */
            foreach (Object btStruct in arlOfBibTexese)
            {

                BibTexStruct bts = (BibTexStruct)btStruct;
                switch (bts.name)
                {
                    case "title":
                        itemArray[0] = bts.value; break;
                    case "author":
                        itemArray[1] = bts.value; break;
                    case "publisher":
                        itemArray[2] = bts.value; break;
                    case "year":
                        itemArray[3] = bts.value; break;
                    case "edition":
                        itemArray[4] = bts.value; break;
                    case "pages":
                        itemArray[5] = bts.value; break;
                    case "editor":
                        itemArray[6] = bts.value; break;
                    case "organization":
                        itemArray[7] = bts.value; break;
                    case "volume":
                        itemArray[8] = bts.value; break;
                }
            }
            return itemArray;
        }
        /// <summary>
        /// cancel event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCancel_Click_1(object sender, EventArgs e)
        {
            if (btnCancel.Text.Equals("Done"))
            {
                //finished
                this.DialogResult = System.Windows.Forms.DialogResult.OK;
            }
            else
            {
                Control.ControlCollection listofcontrol = panelDisplay.Controls;
                int i = 0;
                for (i = 0; i < listofcontrol.Count; i++)
                {
                    FileTransferGui control = (FileTransferGui)listofcontrol[i];
                    {
                        control.btnCancel_Click(control, EventArgs.Empty);
                        i--;
                    }
                }
                this.DialogResult = System.Windows.Forms.DialogResult.No;
            }
            ///checking
            finalise();
            this.Close();
        }
        /// <summary>
        /// prepare the copyitem
        /// </summary>
        private void finalise()
        {
           
            
            Item itemObj = copyItem.ItemObj;

  
            Common.DataObject.FileInfo fileInfoObj = copyItem.FileInfoObj;
            //got file
            if (hasFile == true)
            {
                copyItem.FileInfoObj.Location = Common.Global.getLibFolder();
                copyItem.ItemObj.BPrivate = true;
            }
            else
            {
                copyItem.FileInfoObj.Location = "";
                copyItem.FileInfoObj.FileName = "";
                copyItem.ItemObj.BPrivate = true;
                copyItem.FileInfoObj.Existence = false;
                copyItem.FileInfoObj.Size = 0;
            }

            //got review file
            if (hasReviewFile == true)
            {
                Comment commentObj = copyItem.CommentObj;
                //modify the path to the newly copied review file

                commentObj.ReviewFile = copyItem.CommentObj.ReviewFile.Substring(copyItem.CommentObj.ReviewFile.LastIndexOf("\\") + 1);
            }
            else
            {
                Comment commentObj = copyItem.CommentObj;
                commentObj.ReviewFile = "";
            }
            copyItem.SourceOfItem = ResultItem.ITEM_SOURCE_LOCAL;
        }
    }
}